package co.yixiang.yshop.module.order.service.storeorder;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.enums.OrderDefaultRuleEnum;
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.framework.common.pojo.PageResult;
import co.yixiang.yshop.framework.common.util.http.HttpUtils;
import co.yixiang.yshop.framework.common.util.json.JsonUtils;
import co.yixiang.yshop.framework.redis.util.RedissonUtil;
import co.yixiang.yshop.module.distributor.api.dto.DistributorOrderDTO;
import co.yixiang.yshop.module.distributor.enums.DistributorSettlementTypeEnum;
import co.yixiang.yshop.module.express.dal.dataobject.electronicsorder.ElectronicsOrderDO;
import co.yixiang.yshop.module.express.dal.dataobject.express.ExpressDO;
import co.yixiang.yshop.module.express.dal.redis.express.ExpressRedisDAO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoApiBaseDTO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoElectronicsOrderDTO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoElectronicsOrderGoodsDTO;
import co.yixiang.yshop.module.express.kdniao.model.vo.KdniaoOrderVO;
import co.yixiang.yshop.module.express.kdniao.util.KdniaoUtil;
import co.yixiang.yshop.module.express.service.electronicsorder.ElectronicsOrderService;
import co.yixiang.yshop.module.express.service.express.ExpressService;
import co.yixiang.yshop.module.member.controller.admin.user.vo.UserRespVO;
import co.yixiang.yshop.module.member.controller.admin.userbill.vo.UserBillModifyDTO;
import co.yixiang.yshop.module.member.convert.user.UserConvert;
import co.yixiang.yshop.module.member.dal.dataobject.burypoint.TrendChartRespVO;
import co.yixiang.yshop.module.member.dal.dataobject.user.MemberUserDO;
import co.yixiang.yshop.module.member.dal.mysql.user.MemberUserMapper;
import co.yixiang.yshop.module.member.enums.BillDetailEnum;
import co.yixiang.yshop.module.member.enums.BillEnum;
import co.yixiang.yshop.module.member.enums.LevelGrowthValueEnum;
import co.yixiang.yshop.module.member.service.integralrule.strategy.IntegralRuleContext;
import co.yixiang.yshop.module.member.service.user.MemberUserService;
import co.yixiang.yshop.module.member.service.user.UserService;
import co.yixiang.yshop.module.message.enums.WechatTempateEnum;
import co.yixiang.yshop.module.message.mq.producer.WeixinNoticeProducer;
import co.yixiang.yshop.module.order.controller.admin.storeorder.vo.*;
import co.yixiang.yshop.module.order.controller.admin.storeorderelectronics.vo.StoreOrderElectronicsCreateReqVO;
import co.yixiang.yshop.module.order.controller.app.order.vo.PayInfo;
import co.yixiang.yshop.module.order.convert.storeorder.StoreOrderConvert;
import co.yixiang.yshop.module.order.dal.dataobject.storeorder.StoreOrderDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeordercartinfo.StoreOrderCartInfoDO;
import co.yixiang.yshop.module.order.dal.mysql.storeorder.StoreOrderMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeordercartinfo.StoreOrderCartInfoMapper;
import co.yixiang.yshop.module.order.enums.AdminOrderStatusEnum;
import co.yixiang.yshop.module.order.enums.AppFromEnum;
import co.yixiang.yshop.module.order.enums.OrderLogEnum;
import co.yixiang.yshop.module.order.enums.UpdateOrderEnum;
import co.yixiang.yshop.module.order.service.storeorder.dto.applet.*;
import co.yixiang.yshop.module.order.service.storeorderelectronics.StoreOrderElectronicsService;
import co.yixiang.yshop.module.order.service.storeorderrule.StoreOrderRuleService;
import co.yixiang.yshop.module.order.service.storeorderstatus.StoreOrderStatusService;
import co.yixiang.yshop.module.pay.strategy.PayEnum;
import co.yixiang.yshop.module.product.controller.app.cart.vo.AppStoreCartQueryVo;
import co.yixiang.yshop.module.product.dal.dataobject.campaigndetail.CampaignDetailDO;
import co.yixiang.yshop.module.product.service.campaigndetail.CampaignDetailService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.STORE_ORDER_NOT_EXISTS;

/**
 * 订单 Service 实现类
 *
 * @author yshop
 */
@Slf4j
@Service
@Validated
public class StoreOrderServiceImpl implements StoreOrderService {

    @Resource
    private StoreOrderMapper storeOrderMapper;
    @Resource
    private MemberUserMapper memberUserMapper;
    @Resource
    private StoreOrderCartInfoMapper storeOrderCartInfoMapper;
    @Resource
    private StoreOrderStatusService storeOrderStatusService;
    @Resource
    private AppStoreOrderService appStoreOrderService;
    @Resource
    private ElectronicsOrderService electronicsOrderService;
    @Resource
    private ExpressService expressService;
    @Resource
    private ExpressRedisDAO expressRedisDAO;
    @Resource
    private StoreOrderElectronicsService storeOrderElectronicsService;
    @Resource
    private MemberUserService memberUserService;

    @Resource
    private UserService userService;
    @Resource
    private WeixinNoticeProducer weixinNoticeProducer;
    @Resource
    private RedissonUtil redissonUtil;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private IntegralRuleContext integralRuleContext;
    @Resource
    private StoreOrderRuleService storeOrderRuleService;
    @Resource
    private CampaignDetailService campaignDetailService;

    @Resource
    @Lazy
    private AppDistributorOrderFacade appDistributorOrderFacade;

    /**
     * 小程序appid
     */
    @Value("${wx.miniapp.appid}")
    private String appid;

    /**
     * 小程序秘钥
     */
    @Value("${wx.miniapp.secret}")
    private String secret;

    /**
     * 订单通知标识
     */
    @Value("${wx.order-notice.flag}")
    private Boolean orderNoticeFlag;

    private static String YSHOP_APPLET_NOTICE_TOKEN = "yshop_applet_notice_token";

    @Override
    public Long createStoreOrder(StoreOrderCreateReqVO createReqVO) {
        // 插入
        StoreOrderDO storeOrder = StoreOrderConvert.INSTANCE.convert(createReqVO);
        storeOrderMapper.insert(storeOrder);
        // 返回
        return storeOrder.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStoreOrder(StoreOrderUpdateReqVO updateReqVO) throws IOException {
        // 校验存在
        validateStoreOrderExists(updateReqVO.getId());
        // 更新
        StoreOrderDO updateObj = StoreOrderConvert.INSTANCE.convert(updateReqVO);
        //发货
        if (UpdateOrderEnum.ORDER_SEND.getValue().equals(updateReqVO.getUpdateType())) {
            updateObj.setStatus(OrderInfoEnum.STATUS_WAIT_RECEIVED.getValue());
        }
        storeOrderMapper.updateById(updateObj);

        if (UpdateOrderEnum.ORDER_SEND.getValue().equals(updateReqVO.getUpdateType())) {
            //增加状态
            storeOrderStatusService.create(updateObj.getUid(), updateObj.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
                    "已发货 快递公司：" + updateObj.getDeliveryName() + "快递单号：" + updateObj.getDeliveryId());

            MemberUserDO userInfo = memberUserService.getUser(updateObj.getUid());
            //发送消息队列进行推送消息
            if (userInfo.getLoginType().equals(AppFromEnum.ROUNTINE.getValue())) {
                weixinNoticeProducer.sendNoticeMessage(updateObj.getUid(), WechatTempateEnum.DELIVERY_SUCCESS.getValue(),
                        WechatTempateEnum.SUBSCRIBE.getValue(), updateObj.getOrderId(),
                        updateObj.getPayPrice().toString(), "", updateObj.getDeliveryName(),
                        updateObj.getDeliveryId());
            } else if (userInfo.getLoginType().equals(AppFromEnum.WECHAT.getValue())) {
                weixinNoticeProducer.sendNoticeMessage(updateObj.getUid(), WechatTempateEnum.PAY_SUCCESS.getValue(),
                        WechatTempateEnum.TEMPLATES.getValue(), updateObj.getOrderId(),
                        updateObj.getPayPrice().toString(), "", updateObj.getDeliveryName(),
                        updateObj.getDeliveryId());
            }
            // 非余额支付的订单小程序发货需要发送通知
            StoreOrderDO orderDO = storeOrderMapper.selectById(updateReqVO.getId());
            if (!PayEnum.YUE.getCode().equals(orderDO.getPayType())) {
                sendAppletOrderDeliveryNotice(updateObj, userInfo);
            }
            Integer autoOrderTakeTime = storeOrderRuleService.getOrderRuleCache().getAutoOrderTakeTime();
            //延时队列 七天自动收货
            OrderDefaultRuleEnum ruleEnum = OrderDefaultRuleEnum.ORDER_OUTTIME_UNCONFIRM;
            redissonUtil.delayedOffer(ruleEnum.getKey(), updateReqVO.getOrderId(), autoOrderTakeTime, ruleEnum.getUnit());

        }

    }

    @Override
    public void deleteStoreOrder(Long id) {
        // 校验存在
        validateStoreOrderExists(id);
        // 删除
        StoreOrderDO storeOrderDO = StoreOrderDO.builder()
                .isSystemDel(ShopCommonEnum.DELETE_1.getValue())
                .id(id)
                .build();
        storeOrderMapper.updateById(storeOrderDO);
    }

    @Override
    public void payStoreOrder(Long id) {
        // 校验存在
        validateStoreOrderExists(id);
        StoreOrderDO storeOrderDO = storeOrderMapper.selectById(id);
        storeOrderDO.setPaid(OrderInfoEnum.PAY_STATUS_HAVE_PAID.getValue());
        storeOrderDO.setPayTime(LocalDateTime.now());
        storeOrderMapper.updateById(storeOrderDO);

        //增加状态
        storeOrderStatusService.create(storeOrderDO.getUid(), storeOrderDO.getId(), OrderLogEnum.OFFLINE_PAY.getValue(),
                OrderLogEnum.OFFLINE_PAY.getDesc());
    }

    @Override
    public void takeStoreOrder(Long id) {
        StoreOrderDO storeOrderDO = storeOrderMapper.selectById(id);
        appStoreOrderService.takeOrder(storeOrderDO.getOrderId(), storeOrderDO.getUid());
    }


    private void validateStoreOrderExists(Long id) {
        if (storeOrderMapper.selectById(id) == null) {
            throw exception(STORE_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public StoreOrderRespVO getStoreOrder(Long id) {
        StoreOrderDO storeOrderDO = storeOrderMapper.selectById(id);
        StoreOrderRespVO storeOrderRespVO = StoreOrderConvert.INSTANCE.convert(storeOrderDO);
        MemberUserDO memberUserDO = memberUserMapper.selectById(storeOrderRespVO.getUid());
        UserRespVO userRespVO = UserConvert.INSTANCE.convert4(memberUserDO);
        storeOrderRespVO.setUserRespVO(userRespVO);
        storeOrderRespVO.setStatusStr(this.handleOrderStatus(storeOrderRespVO.getPaid()
                , storeOrderRespVO.getStatus(), storeOrderRespVO.getRefundStatus(), storeOrderRespVO.getIsSystemDel()));
        return storeOrderRespVO;
    }

    @Override
    public List<StoreOrderDO> getStoreOrderList(Collection<Long> ids) {
        return storeOrderMapper.selectBatchIds(ids);
    }


    @Override
    public PageResult<StoreOrderRespVO> getStoreOrderJoinPage(StoreOrderPageReqVO pageReqVO) {
        MPJLambdaWrapper<StoreOrderDO> wrapper = storeOrderMapper.getOrderJoinPageWrapper(pageReqVO)
                .selectAll(StoreOrderDO.class)
                .select(MemberUserDO::getNickname)
                .select(StoreOrderCartInfoDO::getCartInfo)
                .leftJoin(MemberUserDO.class, MemberUserDO::getId, StoreOrderDO::getUid)
                .leftJoin(StoreOrderCartInfoDO.class, StoreOrderCartInfoDO::getOid, StoreOrderDO::getId)
                //混合搜索
                .and(ObjectUtils.isNotNull(pageReqVO.getSearch()), x -> x
                        .like(StoreOrderDO::getRealName, pageReqVO.getSearch())
                        .or()
                        .like(StoreOrderDO::getUid, pageReqVO.getSearch())
                        .or()
                        .like(MemberUserDO::getNickname, pageReqVO.getSearch())
                        .or()
                        .like(StoreOrderCartInfoDO::getCartInfo, pageReqVO.getSearch())
                );
        Integer orderStatus = pageReqVO.getOrderStatus();
        List<Integer> orderStatusSet;
        if (orderStatus != null) {
            //单状态搜索,优先级更高
            orderStatusSet = Collections.singletonList(orderStatus);
        } else {
            orderStatusSet = pageReqVO.getOrderStatusSet();
        }
        // 状态搜索条件
        if (orderStatusSet != null) {
            int size = orderStatusSet.size();
            wrapper.and(w -> {
                for (int i = 0; i < size; i++) {
                    setOrderStatus(w, orderStatusSet.get(i));
                    if (i != size - 1) {
                        w.or();
                    }
                }
            });
        }
        Long campaignId = pageReqVO.getCampaignId();
        if (ObjectUtils.isNotNull(campaignId)) {
            List<CampaignDetailDO> campaignDetails = campaignDetailService.getCampaignDetailListByCampaignId(campaignId);
            List<Long> campaignDetailIds = campaignDetails.stream().map(CampaignDetailDO::getId).collect(Collectors.toList());
            wrapper.in(StoreOrderDO::getCampaignDetailId, campaignDetailIds);
        }

        Page<StoreOrderRespVO> pageInfo = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        Page<StoreOrderRespVO> page = storeOrderMapper.selectJoinPage(pageInfo, StoreOrderRespVO.class, wrapper);
        for (StoreOrderRespVO item : page.getRecords()) {
            List<StoreOrderCartInfoDO> storeOrderCartInfoDOList = storeOrderCartInfoMapper.selectList(
                    new LambdaQueryWrapper<StoreOrderCartInfoDO>().eq(StoreOrderCartInfoDO::getOid, item.getId())
            );
            MemberUserDO memberUserDO = memberUserMapper.selectById(item.getUid());
            UserRespVO userRespVO = UserConvert.INSTANCE.convert4(memberUserDO);
            item.setStoreOrderCartInfoDOList(storeOrderCartInfoDOList);
            item.setUserRespVO(userRespVO);
            item.setStatusStr(this.handleOrderStatus(
                    item.getPaid(), item.getStatus(), item.getRefundStatus(), item.getIsSystemDel()
            ));
        }
        return new PageResult<>(page.getRecords(), page.getTotal());
    }

    private void setOrderStatus(MPJLambdaWrapper<StoreOrderDO> wrapper, Integer status) {
        switch (AdminOrderStatusEnum.toType(status)) {
            //未支付
            case STATUS_0:
                wrapper.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_UNPAID.getValue())
                        .eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_NORMAL.getValue())
                        .eq(StoreOrderDO::getStatus, OrderInfoEnum.STATUS_DEFAULT.getValue());
                break;
            //待发货
            case STATUS_1:
                wrapper.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_HAVE_PAID.getValue())
                        .eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_NORMAL.getValue())
                        .eq(StoreOrderDO::getStatus, OrderInfoEnum.STATUS_DEFAULT.getValue());
                break;
            //待收货
            case STATUS_2:
                wrapper.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_HAVE_PAID.getValue())
                        .eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_NORMAL.getValue())
                        .eq(StoreOrderDO::getStatus, OrderInfoEnum.STATUS_WAIT_RECEIVED.getValue());
                break;
            //待评价
            case STATUS_3:
                wrapper.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_HAVE_PAID.getValue())
                        .eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_NORMAL.getValue())
                        .eq(StoreOrderDO::getStatus, OrderInfoEnum.STATUS_RECEIVED.getValue());
                break;
            //已完成
            case STATUS_4:
                wrapper.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_HAVE_PAID.getValue())
                        .eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_NORMAL.getValue())
                        .eq(StoreOrderDO::getStatus, OrderInfoEnum.STATUS_FINISHED.getValue());
                break;
            //已退款
            case STATUS_5:
                wrapper.eq(StoreOrderDO::getPaid, OrderInfoEnum.PAY_STATUS_UNPAID.getValue())
                        .eq(StoreOrderDO::getRefundStatus, OrderInfoEnum.REFUND_STATUS_HAVE_REFUNDED.getValue());
                break;
            //已删除
            case STATUS_6:
                wrapper.eq(StoreOrderDO::getIsSystemDel, ShopCommonEnum.DELETE_1.getValue());
                break;
            default:
        }
    }

    /**
     * 订单查询
     *
     * @param pageReqVO 分页查询
     * @return 订单vo
     */
    @Override
    public PageResult<StoreOrderRespVO> getStoreOrderPage(StoreOrderPageReqVO pageReqVO) {
//        if (ObjectUtils.isNotNull(campaignId)){
//            List<CampaignDetailDO> campaignDetails = campaignDetailService.getCampaignDetailListByCampaignId(campaignId);
//            List<Long> campaignDetailIds = campaignDetails.stream().map(CampaignDetailDO::getId).collect(Collectors.toList());
//            wrapper.in(StoreOrderDO::getCampaignDetailId,campaignDetailIds);
//        }
        PageResult<StoreOrderDO> pageResult = storeOrderMapper.selectPage(pageReqVO);
        PageResult<StoreOrderRespVO> storeOrderRespVO = StoreOrderConvert.INSTANCE.convertPage(pageResult);
        for (StoreOrderRespVO item : storeOrderRespVO.getList()) {
            LambdaQueryWrapper<StoreOrderCartInfoDO> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(StoreOrderCartInfoDO::getOid, item.getId());
            List<StoreOrderCartInfoDO> storeOrderCartInfoDOList = storeOrderCartInfoMapper.selectList(wrapper);
            MemberUserDO memberUserDO = memberUserMapper.selectById(item.getUid());
            UserRespVO userRespVO = UserConvert.INSTANCE.convert4(memberUserDO);
            item.setStoreOrderCartInfoDOList(storeOrderCartInfoDOList);
            item.setUserRespVO(userRespVO);
            item.setStatusStr(this.handleOrderStatus(
                    item.getPaid(), item.getStatus(), item.getRefundStatus(), item.getIsSystemDel()
            ));
        }
        return storeOrderRespVO;
    }

    @Override
    public List<StoreOrderDO> getStoreOrderList(StoreOrderExportReqVO exportReqVO) {
        return storeOrderMapper.selectList(exportReqVO);
    }

    @Override
    public String printOrder(Long id, Long electId) {
        KdniaoElectronicsOrderDTO queryDTO = new KdniaoElectronicsOrderDTO();
        List<KdniaoElectronicsOrderGoodsDTO> kdniaoElectronicsOrderGoodsDTOList = new ArrayList<>();

        StoreOrderDO storeOrderDO = storeOrderMapper.selectById(id);
        LambdaQueryWrapper<StoreOrderCartInfoDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreOrderCartInfoDO::getOid, storeOrderDO.getId());
        List<StoreOrderCartInfoDO> storeOrderCartInfoDOList = storeOrderCartInfoMapper.selectList(wrapper);
        //组合请求参数
        ElectronicsOrderDO electronicsOrderDO = electronicsOrderService.getElectronicsOrder(electId);
        queryDTO.setMemberID(storeOrderDO.getUid());
        queryDTO.setOrderCode(storeOrderDO.getOrderId());

        ExpressDO expressDO = expressService.getExpress(electronicsOrderDO.getShipperId());
        queryDTO.setShipperCode(expressDO.getCode());
        queryDTO.setCustomerName(electronicsOrderDO.getCustomerName());
        queryDTO.setCustomerPwd(electronicsOrderDO.getCustomerPwd());
        queryDTO.setSendSite(electronicsOrderDO.getSendSite());
        queryDTO.setPaytype(electronicsOrderDO.getPaytype());
        queryDTO.setMonthCode(electronicsOrderDO.getMonthCode());
        queryDTO.setIsReturnSignBill(electronicsOrderDO.getIsReturnSignBill());
        queryDTO.setOperateRequire(electronicsOrderDO.getOperateRequire());
        queryDTO.setExpType(electronicsOrderDO.getExpType());
        queryDTO.setCost(storeOrderDO.getPayPostage().doubleValue());
        queryDTO.setCompany(electronicsOrderDO.getCompany());
        queryDTO.setName(electronicsOrderDO.getName());
        queryDTO.setTel(electronicsOrderDO.getTel());
        queryDTO.setMobile(electronicsOrderDO.getMobile());
        queryDTO.setPostCode(electronicsOrderDO.getPostCode());
        queryDTO.setProvinceName(electronicsOrderDO.getProvinceName());
        queryDTO.setCityName(electronicsOrderDO.getCityName());
        queryDTO.setExpAreaName(electronicsOrderDO.getExpAreaName());
        queryDTO.setAddress(electronicsOrderDO.getAddress());
        queryDTO.setReceiverCompany("yshop");
        queryDTO.setReceiverName(storeOrderDO.getRealName());
        queryDTO.setReceiverTel(storeOrderDO.getUserPhone());
        List<String> stringList = StrUtil.split(storeOrderDO.getUserAddress(), " ");
        if (stringList.size() >= 4) {
            queryDTO.setReceiverProvinceName(stringList.get(0));
            queryDTO.setReceiverCityName(stringList.get(1));
            queryDTO.setReceiverExpAreaName(stringList.get(2));
            queryDTO.setReceiverAddress(stringList.get(3));
        }
        queryDTO.setIsNotice(electronicsOrderDO.getIsNotice());
        queryDTO.setStartDate(electronicsOrderDO.getStartDate());
        queryDTO.setEndDate(electronicsOrderDO.getEndDate());
        queryDTO.setIsReturnTemp(electronicsOrderDO.getIsReturnTemp());
        queryDTO.setRemark(electronicsOrderDO.getRemark());

        int quantity = 0;
        BigDecimal weight = BigDecimal.ZERO;

        for (StoreOrderCartInfoDO storeOrderCartInfoDO : storeOrderCartInfoDOList) {
            KdniaoElectronicsOrderGoodsDTO electronicsOrderGoodsDTO = new KdniaoElectronicsOrderGoodsDTO();
            AppStoreCartQueryVo cartQueryVo = JSON.parseObject(storeOrderCartInfoDO.getCartInfo(),
                    AppStoreCartQueryVo.class);
            electronicsOrderGoodsDTO.setGoodsName(cartQueryVo.getProductInfo().getStoreName());
            electronicsOrderGoodsDTO.setGoodsCode(cartQueryVo.getProductInfo().getId().toString());
            electronicsOrderGoodsDTO.setGoodsQuantity(cartQueryVo.getCartNum());
            electronicsOrderGoodsDTO.setGoodsPrice(cartQueryVo.getTruePrice().doubleValue());
            electronicsOrderGoodsDTO.setGoodsWeight(cartQueryVo.getProductInfo().getAttrInfo().getWeight().doubleValue());
            electronicsOrderGoodsDTO.setGoodsDesc(cartQueryVo.getProductInfo().getDescription());

            kdniaoElectronicsOrderGoodsDTOList.add(electronicsOrderGoodsDTO);

            quantity = quantity + cartQueryVo.getCartNum();
            weight = NumberUtil.add(weight, cartQueryVo.getProductInfo().getAttrInfo().getWeight());
        }
        queryDTO.setQuantity(quantity);
        queryDTO.setWeight(weight.doubleValue());

        KdniaoApiBaseDTO kdniaoApiBaseDTO = expressRedisDAO.get();
        queryDTO.setEBusinessID(kdniaoApiBaseDTO.getEBusinessID());
        queryDTO.setApiKey(kdniaoApiBaseDTO.getApiKey());

        //订单打印
        KdniaoOrderVO kdniaoOrderVO = KdniaoUtil.getOrderInfo(queryDTO, kdniaoElectronicsOrderGoodsDTOList);

        //订单单号回填
        storeOrderDO.setDeliveryId(kdniaoOrderVO.getOrder().getLogisticCode());
        storeOrderDO.setDeliveryName(expressDO.getName());
        storeOrderDO.setDeliverySn(kdniaoOrderVO.getOrder().getShipperCode());
        storeOrderDO.setStatus(OrderInfoEnum.STATUS_WAIT_RECEIVED.getValue());
        storeOrderMapper.updateById(storeOrderDO);

        //增加状态
        storeOrderStatusService.create(storeOrderDO.getUid(), storeOrderDO.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
                "已发货 快递公司：" + storeOrderDO.getDeliveryName() + "快递单号：" + storeOrderDO.getDeliveryId());

        //插入记录电子面单订单记录
        StoreOrderElectronicsCreateReqVO createReqVO = new StoreOrderElectronicsCreateReqVO();
        createReqVO.setOrderSn(storeOrderDO.getOrderId());
        createReqVO.setCustomerName(electronicsOrderDO.getCustomerName());
        createReqVO.setCustomerPwd(electronicsOrderDO.getCustomerPwd());
        createReqVO.setPrintTemplate(kdniaoOrderVO.getPrintTemplate());
        createReqVO.setLogisticCode(kdniaoOrderVO.getOrder().getLogisticCode());
        createReqVO.setShipperCode(kdniaoOrderVO.getOrder().getShipperCode());
        createReqVO.setOrder(JSON.toJSONString(kdniaoOrderVO.getOrder()));
        storeOrderElectronicsService.createStoreOrderElectronics(createReqVO);

        return kdniaoOrderVO.getPrintTemplate();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void closeAfterSaleOrder(Long orderId) {
        storeOrderMapper.closeAfterSaleOrder(orderId, OrderInfoEnum.UNABLE_AFTER_SALES.getValue());
        StoreOrderDO storeOrderDO = storeOrderMapper.selectById(orderId);
        BigDecimal payPrice = storeOrderDO.getPayPrice();
        //积分
        integralRuleContext.execute(BillDetailEnum.CONSUME, storeOrderDO.getUid(), payPrice);
        //成长值
        userService.addGrowthValue(storeOrderDO.getUid(), LevelGrowthValueEnum.CONSUME.getType(), payPrice);
        //商品积分
        MemberUserDO user = memberUserService.getUser(storeOrderDO.getUid());
        //订单关闭售后，奖励积分
        memberUserService.addIntegral(UserBillModifyDTO.builder()
                .uid(storeOrderDO.getUid())
                .amount(storeOrderDO.getGainIntegral())
                .afterAmount(NumberUtil.add(user.getIntegral(), storeOrderDO.getGainIntegral()))
                .typeEnum(BillDetailEnum.TYPE_9)
                .categoryEnum(BillDetailEnum.CATEGORY_2)
                .pmType(BillEnum.PM_1)
                .linkId(orderId)
                .build());

        appDistributorOrderFacade.updateDistributorOrder(new DistributorOrderDTO().setOid(storeOrderDO.getId()).setDistributorSettlementType(DistributorSettlementTypeEnum.COMPLETE.getType()));
    }

    @Override
    public List<TrendChartRespVO> getTrendChart() {
        return storeOrderMapper.getTrendChart();
    }

    /**
     * 处理订单状态
     *
     * @param payStatus    支付状态
     * @param status       订单状态
     * @param refundStatus 退款状态
     * @param del          删除标准
     * @return 订单状态
     */
    private String handleOrderStatus(Integer payStatus, Integer status, Integer refundStatus, Integer del) {
        String statusName = "";
        if (del == 1) {
            statusName = "已删除";
        } else if (payStatus == 0 && status == 0) {
            statusName = "未支付";
        } else if (payStatus == 0 && status == 4) {
            statusName = "已取消";
        } else if (payStatus == 1 && status == 0 && refundStatus == 0) {
            statusName = "未发货";
        } else if (payStatus == 1 && status == 1 && refundStatus == 0) {
            statusName = "待收货";
        } else if (payStatus == 1 && status == 2 && refundStatus == 0) {
            statusName = "待评价";
        } else if (payStatus == 1 && status == 3 && refundStatus == 0) {
            statusName = "已完成";
        } else if (payStatus == 1 && refundStatus == 2) {
            statusName = "已退款";
        } else if (payStatus == 1 && refundStatus == 1) {
            statusName = "退款中";
        }
        return statusName;
    }


    private void sendAppletOrderDeliveryNotice(StoreOrderDO orderDO, MemberUserDO memberUserDO) throws IOException {
        if (!orderNoticeFlag) return;
        //获取token
        StoreOrderDO storeOrderDO = storeOrderMapper.selectById(orderDO.getId());
        PayInfo payInfo = JsonUtils.parseObject(storeOrderDO.getPayInfo(), PayInfo.class);
        assert payInfo != null;
        if (Objects.nonNull(payInfo.getOut_trade_no()) && !payInfo.getOut_trade_no().contains("APPLET")) return;
        String token =  HttpUtils.getAppletNoticeToken(appid, secret);
        TokenResult result = JsonUtils.parseObject(token, TokenResult.class);
        AppletNoticeDTO appletNoticeDto = new AppletNoticeDTO();
        OrderKey orderKey = new OrderKey(2, payInfo.getTransaction_id());
        List<ShippingList> list = new ArrayList<>();
        ShippingList shippingList = new ShippingList();
        LambdaQueryWrapper<StoreOrderCartInfoDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreOrderCartInfoDO::getOid, storeOrderDO.getId());
        List<StoreOrderCartInfoDO> storeOrderCartInfoDOList = storeOrderCartInfoMapper.selectList(wrapper);
        JSONObject jsonObject = JSON.parseObject(storeOrderCartInfoDOList.get(0).getCartInfo());
        JSONObject productInfo = jsonObject.getJSONObject("productInfo");
        String desc = "";
        String sku = productInfo.getJSONObject("attrInfo").getString("sku");
        String name = productInfo.getString("storeName");
        if (storeOrderCartInfoDOList.size() <= 1) {
            desc = name + "|" + sku;
        } else {
            desc = name + "|" + sku + "等";
        }
        shippingList.setContact(new Contact("", ""))
                .setItem_desc(desc)
                .setExpress_company(storeOrderDO.getDeliverySn())
                .setTracking_no(storeOrderDO.getDeliveryId());
        list.add(shippingList);
        appletNoticeDto.setOrder_key(orderKey).setDelivery_mode(1).setLogistics_type(1)
                .setUpload_time(DateUtil.format(new Date(), "yyyy-MM-dd'T'HH:mm:ssXXX")).setPayer(new Payer(memberUserDO.getRoutineOpenId()))
                .setShipping_list(list);
        assert result != null;
        String res = HttpUtils.sendAppletNotice(result.getAccess_token(), JsonUtils.toJsonString(appletNoticeDto));
        log.info("小程序发货通知结果：{}", res);
    }


}
